#ifndef SYLAR_IOMANAGER_H
#define SYLAR_IOMANAGER_H
#include "scheduler.h"
#include <sys/epoll.h>
namespace sylar
{
    class IOManager : public Scheduler
    {
    public:
        typedef std::shared_ptr<IOManager> ptr;
        typedef RWMutex RWMutexType;
        
        enum Event
        {
            NONE = 0x0,
            READ = 0x1,
            WRITE = 0x2
        };

    private:
        struct FdContext
        {
            typedef Mutex MutexType;

            struct EventContext
            {
                Scheduler *shceduler = nullptr;
                std::shared_ptr<Fiber> fiber = nullptr;
                std::function<void()> cb;
            };

            EventContext read;  // 读时间
            EventContext write; // 写时间
            int fd=0;
            Event m_events = NONE;
            mutable MutexType mutex;
        };

    public:
        IOManager(size_t thread_num = 1, bool use_caller = true, const std::string &name = "Srne");
        ~IOManager() override;
        int addEvent(int fd, Event event, std::function<void()> cb = nullptr);
        // 1 ok 0 retry -1 error
        bool delEvent(int fd, Event event);
        bool cancelEvent(int fd, Event event);
        bool cancleAll(int fd);
        static IOManager *GetThis();

    protected:
        void tickle() override;
        bool stopping() override;
        void idle() override;

        void contextResize(size_t size);

    private:
        int m_epfd = 0;
        int m_tickleFds[2];
        std::atomic<size_t> m_pendingEventCount = 0;
        mutable RWMutexType m_mutex;
        std::vector<FdContext *> m_fdContexts;
    };

}

#endif